﻿using Sidvall.UI.Dialogs;
using System;
using System.Threading.Tasks;

namespace Sidvall.UI.Uwp.Dialogs
{
    public sealed partial class WebSecurityDialog
    {
        #region Public Members

        #region InitializeContext

        public void InitializeContext(LogOffDialogContext context)
        {
            if (context == null)
                throw new System.ArgumentNullException("context");

            var client = Sidvall.SystemContext.Current.AuthenticationManager.GetAuthenticationClient(context.LogOffEndpoint);
            var startUrl = client.CreateLogOffAddress(context.IdentityToken, context.RedirectAddress);
            this.Title = "Log Off";
            this.LoggingOn = false;
            this.WebView.Navigate(new System.Uri(startUrl));
        }
        public void InitializeContext(LogOnDialogContext context)
        {
            if (context == null)
                throw new System.ArgumentNullException("context");

            var client = Sidvall.SystemContext.Current.AuthenticationManager.GetAuthenticationClient(context.AuthorizeEndpoint);
            var startUrl = client.CreateAuthorizeAddress(context.ClientId, context.ResponseType, context.Scope, context.RedirectAddress, context.State, context.Nonce,
                context.LogOnHint, context.AuthenticationContextReferences, context.Prompt, context.ResponseMode, context.CodeChallenge, context.CodeChallengeMethod, context.AdditionalValues);
            this.Title = "Log On";
            this.LoggingOn = true;
            this.WebView.Navigate(new System.Uri(startUrl));
        }

        #endregion
        #region ShowAsync

        public async Task ShowAsync(LogOnDialogContext logOnContext, LogOffDialogContext logOffContext, object owner)
        {
            if ((logOnContext == null) && (logOffContext == null))
                return;
            var page = owner as Windows.UI.Xaml.Controls.Page;
            ControlManager.SetHeight(this, page.ActualHeight, 650);
            ControlManager.SetWidth(this, page.ActualWidth, 800);
            this.LogOffContext = logOffContext;
            this.LogOnContext = logOnContext;
            if (this.LogOffContext != null)
            {
                InitializeContext(this.LogOffContext);
            }
            else
            {
                InitializeContext(this.LogOnContext);
            }
            await ShowAsync();
        }

        #endregion

        #endregion
        #region Private Members

        private bool LoggingOn { get; set; }
        private LogOffDialogContext LogOffContext { get; set; }
        private LogOnDialogContext LogOnContext { get; set; }

        #region CloseView

        private void CloseView()
        {
            if (this.LogOnContext != null)
            {
                InitializeContext(this.LogOnContext);
            }
            else
            {
                Hide();
            }
        }

        #endregion

        #endregion
        #region Events

        #region WebView_NavigationStarting

        private void WebView_NavigationStarting(Windows.UI.Xaml.Controls.WebView sender, Windows.UI.Xaml.Controls.WebViewNavigationStartingEventArgs args)
        {
            System.Uri callbackUri;

            if (this.LoggingOn)
            {
                callbackUri = new System.Uri(this.LogOnContext.RedirectAddress);
                if (args.Uri.ToString().StartsWith(callbackUri.AbsoluteUri, System.StringComparison.OrdinalIgnoreCase))
                {
                    this.LogOnContext.AuthorizeResponse = Sidvall.SystemContext.Current.AuthenticationManager.ParseAuthorizeResponseFromAddress(args.Uri.AbsoluteUri);
                    args.Cancel = true;
                    Hide();
                }
            }
            else
            {
                callbackUri = new System.Uri(this.LogOffContext.RedirectAddress);
                if (args.Uri.ToString().StartsWith(callbackUri.AbsoluteUri, System.StringComparison.OrdinalIgnoreCase))
                {
                    this.LogOffContext.Response = args.Uri.AbsoluteUri;
                    args.Cancel = true;
                    CloseView();
                }
            }
        }

        #endregion
        #region WebView_NavigationCompleted

        private async void WebView_NavigationCompleted(Windows.UI.Xaml.Controls.WebView sender, Windows.UI.Xaml.Controls.WebViewNavigationCompletedEventArgs args)
        {
            if (!this.LoggingOn)
            {
                var html = await this.WebView.InvokeScriptAsync("eval", new string[] { "document.body.innerHTML" });
                if (html.IndexOf("you are now logged out", System.StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    CloseView();
                }
            }
        }

        #endregion

        #endregion
        #region Constructors

        public WebSecurityDialog()
        {
            this.InitializeComponent();

            this.WebView.NavigationStarting += WebView_NavigationStarting;
            this.WebView.NavigationCompleted += WebView_NavigationCompleted;
        }

        #endregion
    }
}
